/*HT1621/FUTABA VFD AIDA64 SERIAL MONITOR Arudino版驱动源代码
2020-08-30
EDITED BY YIZHOU WANG

更新日志


v0.0.1 beta ver. 2020.08.30
增加debug模式，对HT1621进行适配
已知bug：
对于显示0x20时可能会导致显示乱码，并且在显示100%时会出现占位显示问题
时序问题：
若显示结束后arduino接受到的数据是残缺的可能会导致数据为空白，建议将aida64传输数据的时间延长至9秒，若低于这个值则此bug有几率发生
v0.0.2 beta ver.

增加对FUTABA VFD屏幕的适配,并增加了对应的debug模式

v0.1 alpha ver. 2020.09.04
增加数据完整性检查
在HT1621显示模式下，Pr为百分比(perc.);.C为摄氏度符号
tCPU,tGPU为CPU,GPU温度
UCPU,UGPU为CPU,GPU占用率
Setting模式被删除，若调整波特率需要在程序中编辑。
debug模式被注释删除,若启用debug模式可能会因误操作无法进入正式显示程序

v0.1.1 alpha ver. 2020.09.04
增加串口向导设置

v0.1.2 Publish ver. 2021.02.09
修复数据乱码问题
程序中增加ClearSerial函数以清空串口缓存解决该问题
*/
#include<Wire.h>
#include<EEPROM.h>


#define Bias_Duty  0x52   /*设置液晶屏COM口笔端数量 4COM,1/3BIAS*/
#define Rc256 0x30        /*启用内部RC振荡*/
#define LCD_ON 0x6        /*打开LCD偏置发生器*/
#define SIS_EN 0x2        /*打开系统振荡*/
#define TONE_OFF 0x10    /*内部蜂鸣器关*/
#define TONE_2K 0x13     /*打开蜂鸣器并且频率为2KHz*/
#define TONE_4K 0x12     /*打开蜂鸣器并且频率为4KHz*/
#define Cr32K768 0x28    /*打开外部石英振荡器*/
#define TMR_en 0x0c      /*时基输出有效*/
#define TMR_clr 0x18     /*时基输出清零*/
#define IRQen 0x10       /*外部时基打开*/
#define WDT_en 0x02      /*看门狗有效*/
#define WDT1HZ 0x40      /*看门狗时基打开*/ 

#define R24C16ADDR=0xA1
#define W24C16ADDR=0xA0



#define CLK 4 //时钟（两种显示模式复用）
#define DAT 5 //数据引脚（两种显示模式复用）
#define CS 6 //Chip select 选中使能（HT1621 LCD显示时）；Command Switch(FUTABA VFD显示时)；复用
#define KEY 7//正忙检测引脚，复用：在设置为futabaVFD显示时，变为RS引脚
#define EN 8//futabaVFD专用ENABLE使能引脚
#define FUTABA16EN 12//futabaVFD16位屏使能引脚
#define DebugMode A7//进入debug模式，输入高电平开启
#define Setting A3//进入设置模式
#define dispM1 A1
#define dispM2 A2
int SwitchDisplayMode=0;//若该值为1，则以HT1621作为显示设备，若该值为0，则以futabaVFD作为显示设备

int CPUUtiR;//CPU占用率
int GPUUtiR;//GPU占用率
int CPUtempR;//CPU温度
int GPUtempR;//GPU温度
char frame[40];//原始数据存放区

int UGPUge;
int UGPUshi;
int UGPUbai;

int ValUGPU;

int TGPUge;
int TGPUshi;
int TGPUbai;

int ValTGPU;

int UCPUge;
int UCPUshi;
int UCPUbai;

int URAMbai;
int URAMshi;
int URAMge;

int ValUCPU;

int TCPUge;//在数据在3位时这位必为个位
int TCPUshi;//这个十位有可能是个位
int TCPUbai;//aida64格式不定，所以百位有可能是个位或十位

int ValTCPU;

int countTimes=0;//循环次数
  int empC=B00000000;
  int num1=B00000110;
  int num2=B01101101;
  int num3=B01001111;
  int num4=B11000110;
  int num5=B11001011;
  int num6=B11101011;
  int num7=B00001110;
  int num8=B11101111;
  int num9=B11001111;
  int num0=B10101111;
  
  int chaA=B11101110;
  int chaB=B11100011;
  int chaC=B10101001;
  int chaD=B01100111;
  int chaE=B11101001;
  int chaF=B11101000;
  int chaP=B11101100;
  int chaU=B10100111;
  int chaO=B10101111;
  int chaV=B00100011;
  int chaR=B01100000;//地址0-8
  int chaT=B11100001;
  int chaG=B10101011;
  int chaL=B10100001;
  int chaH=B11100110;
  
  int ad2num1=B01100000;
  int ad2num2=B11010110;
  int ad2num3=B11110100;
  int ad2num4=B01101100;
  int ad2num5=B10111100;
  int ad2num6=B10111110;
  int ad2num7=B11100000;
  int ad2num8=B11111110;
  int ad2num9=B11111100;
  int ad2num0=B11111010;

  int ad2chaP=B11001110;
  int ad2chaR=B00000110;
  
  int ad2chatC=B10011011;
  
  int ad2chaG=B10111010;
  int ad2chaO=B00110110;
  int ad2chaD=B01110110;
  int ad2chaB=B00111110;
  int ad2chaA=B11101110;
  int ad2chaN=B00100110;
  int ad2chaE=B10011110;

  char CustomChar_FUTABAvfd[5]={B00000011,B00111011,B01000100,B01000100,B01000100};//自定义字符：：摄氏度，仅适用于futabaVFD屏

void ClearFrame()
{
for(int i=0;i<40;i++)
{
  frame[i]=0x00;
  }
}


/************************************SEGMENT VFD START*******************************************/
void SendDataSEGVFD(char* datas)
{
  Serial.write(0xFE);
  Serial.write(0x48);//初始化数据帧*/
  for(int i=0;i<10;i++)
  {
  Serial.write(*datas);
  datas++;
  }
  Serial.write(0X00);
  Serial.write(0X00);
  Serial.write(0X00);
  Serial.write(0X00);//显示符号*/
  
  Serial.write(0x8F);
  
  Serial.write(0x0D);
  Serial.write(0x0A);
  }
/************************************SEGMENT VFD END*******************************************/


/*************************************FUTABA VFD START*******************************************/

void CustomChar_futaba6302_display(int CGRAMaddr)//自定义字符函数,CGRAMaddr只能取到0x00-0x07，否则超出CGRAM范围无效,dispAddr是你想要显示数据的位置
{
  digitalWrite(CS,LOW);
  write_futaba6302(0x40+CGRAMaddr);
  delayMicroseconds(5);
  for(int i=0;i<5;i++)
  {
  write_futaba6302(CustomChar_FUTABAvfd[i]);
  delayMicroseconds(5);
    }
  digitalWrite(CS,HIGH);//将数据写入CGRAM
  delay(100);
  }

void WriteOneChar_futaba6302(unsigned char x, unsigned char chr)
{
  digitalWrite(CS, LOW);  //开始传输
  write_futaba6302(0x20 + x); //地址寄存器起始位置
  write_futaba6302(chr + 0x30);
  digitalWrite(CS, HIGH); //停止传输
  
  digitalWrite(CS, LOW);//开始传输
  write_futaba6302(0xe8);     //地址寄存器起始位置
  digitalWrite(CS, HIGH); 
}

void init_futaba6302(int digit,int brightness)//futaba VFD初始化程序,默认digit为0x07(8位显示),brightness=0xff(亮度设置，255最亮)
{
  cmd_futaba6302_double(0xe0,digit);
  cmd_futaba6302_double(0xe4,brightness);
}  
void write_futaba6302(unsigned char w_data)//futaba VFD写入数据程序,低位先开始传输
{
  unsigned char i;
  for (i = 0; i < 8; i++)
  {
    digitalWrite(CLK, LOW);
    if ( (w_data & 0x01) == 0x01)
    {
      digitalWrite(DAT, HIGH);
    }
    else
    {
      digitalWrite(DAT, LOW);
    }
    w_data >>= 1;
    digitalWrite(CLK, HIGH);
  }
}

void cmd_futaba6302_double(unsigned char command,unsigned char command2)//futaba VFD写指令程序（双指令），对CS进行操作
{
  digitalWrite(CS, LOW);
  write_futaba6302(command);
  delayMicroseconds(5);
  write_futaba6302(command2);
  digitalWrite(CS, HIGH);
  delayMicroseconds(5);
}

void cmd_futaba6302(unsigned char command)//futaba VFD写指令程序（单指令），对CS进行操作
{
  digitalWrite(CS, LOW);
  write_futaba6302(command);
  digitalWrite(CS, HIGH);
  delayMicroseconds(5);
}

void printChar_custom_futaba6302(unsigned char p,int val)//p为显示位置 val为CGRAM地址
{
  digitalWrite(CS, LOW);  //开始传输
   write_futaba6302(0x20+p);
   write_futaba6302(val);
  digitalWrite(CS, HIGH); //停止传输
  
  digitalWrite(CS, LOW);//开始传输
  write_futaba6302(0xe8);     //地址寄存器起始位置
  digitalWrite(CS, HIGH); //停止传输
  }

void printChar_futaba6302(unsigned char p,char *string)//显示字符，x从0-7
{
  digitalWrite(CS, LOW);  //开始传输
  write_futaba6302(0x20 + p); //地址寄存器起始位置
  while (*string)
  {
    write_futaba6302(*string); //ascii与对应字符表转换
    string++;
  }
  digitalWrite(CS, HIGH); //停止传输
  
  digitalWrite(CS, LOW);//开始传输
  write_futaba6302(0xe8);     //地址寄存器起始位置
  digitalWrite(CS, HIGH); //停止传输
  }

void Clear_futaba6302()
{
  printChar_futaba6302(0,"        ");
  }

/*********************************FUTABA VFD****************************************************/


/******************************JUNIOR FUNCTION**************************************************/

int calcAllValue(int bai,int shi,int ge)
{
  if(shi==88&&ge==88)//如十位或个位均无数据，则实际数值为百位上的数值(若aida64接收到的是个空格"0x20"，则返回十进制数值88)
  return bai;
  if(bai!=88 && shi!=88 && ge==88)
  return bai*10+shi;
  if(bai!=88)
  return bai*100+shi*10+ge;
  }
/***************************************END****************************************************/

/*********************************HT1621 LCD***************************************************/
void DelayKey(unsigned int WaitTime)
{            //输入精确到0.1S，检测正忙
   delay(WaitTime);
    if(!KEY)
    {
      delay(2);
      while(!KEY) 
      {
        delay(2);
        }
    }
    else
    {
    delay(10);
    }   
}

void HT1621Delay()//51原程序延时4个机器周期，约4us，12M晶振下
{
  delayMicroseconds(4);
  }
  
void WrCmd(unsigned char Cmd)/*写控制命令函数*/
{
 
 unsigned char i;
 unsigned char CmdByte=0x80;
 digitalWrite(CS,LOW); /*低电平有效*/
 for(i=0;i<4;i++)
 {
  if((CmdByte&0x80)==0)//值1：B10000000 值2：B00000000
  {
   digitalWrite(DAT,LOW);
   digitalWrite(CLK,LOW);
   HT1621Delay();
   digitalWrite(CLK,HIGH);
  }
  else
  {
   digitalWrite(DAT,HIGH);
   digitalWrite(CLK,LOW);
   HT1621Delay();
   digitalWrite(CLK,HIGH);
  }
  CmdByte<<=1;//传输B1000
 }//
 
 for(i=0;i<8;i++)
 {
  if((Cmd&0x80)==0)
  {
   digitalWrite(DAT,LOW);
   digitalWrite(CLK,LOW);
   HT1621Delay();
   digitalWrite(CLK,HIGH);
  }
  else
  {
   digitalWrite(DAT,HIGH);
   digitalWrite(CLK,LOW);
   HT1621Delay();
   digitalWrite(CLK,HIGH);//开始正式传输指令 长度为8位
  }
  Cmd<<=1;
 }
  digitalWrite(CS,HIGH);
}

void WrAddDdat(unsigned char datas,unsigned char addr)/*写入数据函数*/
{
 
 unsigned char i;
 unsigned char DataByte=0xA0;
 digitalWrite(CS,LOW); /*低电平有效*/
 for(i=0;i<3;i++)
 {
  if((DataByte&0x80)==0)//值1：B10000000 值2：B00000000
  {
   digitalWrite(DAT,LOW);
   digitalWrite(CLK,LOW);
   HT1621Delay();
   digitalWrite(CLK,HIGH);
  }
  else
  {
   digitalWrite(DAT,HIGH);
   digitalWrite(CLK,LOW);
   HT1621Delay();
   digitalWrite(CLK,HIGH);
  }
  DataByte<<=1;//传输B101
 }//
 
 addr=addr<<2;
 
 for(i=0;i<6;i++)
 {
  if((addr&0x80)==0)
  {
   digitalWrite(DAT,LOW);
   digitalWrite(CLK,LOW);
   HT1621Delay();
   digitalWrite(CLK,HIGH);
  }
  else
  {
   digitalWrite(DAT,HIGH);
   digitalWrite(CLK,LOW);
   HT1621Delay();
   digitalWrite(CLK,HIGH);//开始传输地址信息
  }
  addr<<=1;
 }

 for(i=0;i<8;i++)
 {
  if((datas&0x80)==0)
  {
   digitalWrite(DAT,LOW);
   digitalWrite(CLK,LOW);
   HT1621Delay();
   digitalWrite(CLK,HIGH);
  }
  else
  {
   digitalWrite(DAT,HIGH);
   digitalWrite(CLK,LOW);
   HT1621Delay();
   digitalWrite(CLK,HIGH);//开始传输数据信息
  }
  datas<<=1;
 }
 
  digitalWrite(CS,HIGH);
}

void ClearLcdHT1621()
{
  unsigned char i;
 for(i=0;i<90;i+=2)
 {
 WrAddDdat(0x00,i);
 }
}

void Init_HT1621()
{
 WrCmd(Bias_Duty);
 WrCmd(Rc256);
 WrCmd(SIS_EN);
 WrCmd(LCD_ON);
 WrCmd(TONE_OFF);//WrCMD函数OK！
  }



/*******************************************HT1621****************************************************/




/****************************************DEBUG FUNCTION***************************************************/
void SerialDebugForOnline()
{
  while(1)
       {
        for(int i=0;i<8;i++)
        {
        SerialDebugforBUF(frame[i]);
        delay(2000);
        }
        }
  }
void FutabaVFDdebug()
{
  printChar_futaba6302(1,"TEST");
  }

void SerialDebug()//HT1621+ 串口
{
  ClearLcdHT1621();
  while(1)
  {
  int rec;
  while(Serial.available()>0)
  {
    delay(100);
    rec=Serial.read();
    }
    switch(rec/16)//获取高4位
    {
      case 1:
      WrAddDdat(num1,2);
      break;
      case 2:
       WrAddDdat(num2,2);
      break;
      case 3:
       WrAddDdat(num3,2);
      break;
      case 4:
       WrAddDdat(num4,2);
      break;
      case 5:
      WrAddDdat(num5,2);
      break;
      case 6:
       WrAddDdat(num6,2);
      break;
      case 7:
       WrAddDdat(num7,2);
      break;
      case 8:
       WrAddDdat(num8,2);
      break;
       case 9:
      WrAddDdat(num9,2);
      break;
      case 0:
       WrAddDdat(num0,2);
      break;
      case 10:
       WrAddDdat(chaA,2);
      break;
      case 11:
       WrAddDdat(chaB,2);
      break;
      case 12:
       WrAddDdat(chaC,2);
      break;
      case 13:
       WrAddDdat(chaD,2);
      break;
      case 14:
       WrAddDdat(chaE,2);
      break;
      case 15:
       WrAddDdat(chaF,2);
      break;
      }
      switch(rec%16)//获取低4位
    {
      case 1:
      WrAddDdat(num1,4);
      break;
      case 2:
       WrAddDdat(num2,4);
      break;
      case 3:
       WrAddDdat(num3,4);
      break;
      case 4:
       WrAddDdat(num4,4);
      break;
       case 5:
      WrAddDdat(num5,4);
      break;
      case 6:
       WrAddDdat(num6,4);
      break;
      case 7:
       WrAddDdat(num7,4);
      break;
      case 8:
       WrAddDdat(num8,4);
      break;
       case 9:
      WrAddDdat(num9,4);
      break;
      case 0:
       WrAddDdat(num0,4);
      break;
      case 10:
       WrAddDdat(chaA,4);
      break;
      case 11:
       WrAddDdat(chaB,4);
      break;
      case 12:
       WrAddDdat(chaC,4);
      break;
      case 13:
       WrAddDdat(chaD,4);
      break;
      case 14:
       WrAddDdat(chaE,4);
      break;
      case 15:
       WrAddDdat(chaF,4);
      break;
      }
      WrAddDdat(chaH,6);
  }
}

void SerialDebugforBUF(char check)
{
  ClearLcdHT1621();

    switch(check/16)//获取高4位
    {
      case 1:
      WrAddDdat(num1,2);
      break;
      case 2:
       WrAddDdat(num2,2);
      break;
      case 3:
       WrAddDdat(num3,2);
      break;
      case 4:
       WrAddDdat(num4,2);
      break;
       case 5:
      WrAddDdat(num5,2);
      break;
      case 6:
       WrAddDdat(num6,2);
      break;
      case 7:
       WrAddDdat(num7,2);
      break;
      case 8:
       WrAddDdat(num8,2);
      break;
       case 9:
      WrAddDdat(num9,2);
      break;
      case 0:
       WrAddDdat(num0,2);
      break;
      case 10:
       WrAddDdat(chaA,2);
      break;
      case 11:
       WrAddDdat(chaB,2);
      break;
      case 12:
       WrAddDdat(chaC,2);
      break;
      case 13:
       WrAddDdat(chaD,2);
      break;
      case 14:
       WrAddDdat(chaE,2);
      break;
      case 15:
       WrAddDdat(chaF,2);
      break;
      }
      switch(check%16)//获取低4位
    {
      case 1:
      WrAddDdat(num1,4);
      break;
      case 2:
       WrAddDdat(num2,4);
      break;
      case 3:
       WrAddDdat(num3,4);
      break;
      case 4:
       WrAddDdat(num4,4);
      break;
       case 5:
      WrAddDdat(num5,4);
      break;
      case 6:
       WrAddDdat(num6,4);
      break;
      case 7:
       WrAddDdat(num7,4);
      break;
      case 8:
       WrAddDdat(num8,4);
      break;
       case 9:
      WrAddDdat(num9,4);
      break;
      case 0:
       WrAddDdat(num0,4);
      break;
      case 10:
       WrAddDdat(chaA,4);
      break;
      case 11:
       WrAddDdat(chaB,4);
      break;
      case 12:
       WrAddDdat(chaC,4);
      break;
      case 13:
       WrAddDdat(chaD,4);
      break;
      case 14:
       WrAddDdat(chaE,4);
      break;
      case 15:
       WrAddDdat(chaF,4);
      break;
      }
      WrAddDdat(chaH,6);
  }

void debugModeDisp(int delayTi)
{
  int i;
 int j;
 int priDat;
 ClearLcdHT1621();


for(j=0;j<16;j++)
switch(j)
{
case 1:
 for(i=0;i<8;i+=2)
    {
     WrAddDdat(num1,i); 
    delay(delayTi);
    }  
    break;
    case 2:
 for(i=0;i<8;i+=2)
    {
     WrAddDdat(num2,i); 
    delay(delayTi);
    }  
    break;

    case 3:
 for(i=0;i<8;i+=2)
    {
     WrAddDdat(num3,i); 
    delay(delayTi);
    }  
    break;
    case 4:
 for(i=0;i<8;i+=2)
    {
     WrAddDdat(num4,i); 
    delay(delayTi);
    }  
    break;
    case 5:
 for(i=0;i<8;i+=2)
    {
     WrAddDdat(num5,i); 
    delay(delayTi);
    }  
    break;
    case 6:
 for(i=0;i<8;i+=2)
    {
     WrAddDdat(num6,i); 
    delay(delayTi);
    }  
    break;

    case 7:
 for(i=0;i<8;i+=2)
    {
     WrAddDdat(num7,i); 
    delay(delayTi);
    }  
    break;
    case 8:
 for(i=0;i<8;i+=2)
    {
     WrAddDdat(num8,i); 
    delay(delayTi);
    }  
    break;
     case 9:
 for(i=0;i<8;i+=2)
    {
     WrAddDdat(num9,i); 
    delay(delayTi);
    }  
    break;
    case 0:
 for(i=0;i<8;i+=2)
    {
     WrAddDdat(num0,i); 
    delay(delayTi);
    }  
    break;
 case 10:
 for(i=0;i<8;i+=2)
    {
     WrAddDdat(chaA,i); 
    delay(delayTi);
    }  
    break;
     case 11:
 for(i=0;i<8;i+=2)
    {
     WrAddDdat(chaB,i); 
    delay(delayTi);
    }  
    break;
    case 12:
 for(i=0;i<8;i+=2)
    {
     WrAddDdat(chaC,i); 
    delay(delayTi);
    }  
    break;

    case 13:
 for(i=0;i<8;i+=2)
    {
     WrAddDdat(chaD,i); 
    delay(delayTi);
    }  
    break;
    case 14:
 for(i=0;i<8;i+=2)
    {
     WrAddDdat(chaE,i); 
    delay(delayTi);
    }  
    break;
     case 15:
 for(i=0;i<8;i+=2)
    {
     WrAddDdat(chaF,i); 
    delay(delayTi);
    }  
    break;
}

for(j=0;j<10;j++)
switch(j)
{
case 1:
 for(i=10;i<20;i+=2)
    {
     WrAddDdat(ad2num1,i); 
    delay(delayTi);
    }  
    break;
    case 2:
 for(i=10;i<20;i+=2)
    {
     WrAddDdat(ad2num2,i); 
    delay(delayTi);
    }  
    break;

    case 3:
 for(i=10;i<20;i+=2)
    {
     WrAddDdat(ad2num3,i); 
    delay(delayTi);
    }  
    break;
    case 4:
 for(i=10;i<20;i+=2)
    {
     WrAddDdat(ad2num4,i); 
    delay(delayTi);
    }  
    break;
    case 5:
 for(i=10;i<20;i+=2)
    {
     WrAddDdat(ad2num5,i); 
    delay(delayTi);
    }  
    break;
    case 6:
 for(i=10;i<20;i+=2)
    {
     WrAddDdat(ad2num6,i); 
    delay(delayTi);
    }  
    break;

    case 7:
 for(i=10;i<20;i+=2)
    {
     WrAddDdat(ad2num7,i); 
    delay(delayTi);
    }  
    break;
    case 8:
 for(i=10;i<20;i+=2)
    {
     WrAddDdat(ad2num8,i); 
    delay(delayTi);
    }  
    break;
     case 9:
 for(i=10;i<20;i+=2)
    {
     WrAddDdat(ad2num9,i); 
    delay(delayTi);
    }  
    break;
    case 0:
 for(i=10;i<20;i+=2)
    {
     WrAddDdat(ad2num0,i); 
    delay(delayTi);
    }  
    break;

}
ClearLcdHT1621();
WrAddDdat(chaL,0);
WrAddDdat(chaC,2);
WrAddDdat(chaD,4);

WrAddDdat(ad2chaD,18);
WrAddDdat(ad2chaO,16);
WrAddDdat(ad2chaN,14);
WrAddDdat(ad2chaE,12);
delay(2000);
ClearLcdHT1621();
  }
int ascii2dec(char inp)//将原始ASCII表示的数字转换为可被单片机计算的数字
{
  switch(inp)
  {
    case 0x30:
    return 0;
    break;
    
    case 0x31:
    return 1;
    break;

    case 0x32:
    return 2;
    break;

    case 0x33:
    return 3;
    break;

    case 0x34:
    return 4;
    break;

    case 0x35:
    return 5;
    break;

    case 0x36:
    return 6;
    break;

    case 0x37:
    return 7;
    break;

    case 0x38:
    return 8;
    break;

    case 0x39:
    return 9;
    break;

    case 0x20:
    return 88;
    break;
    }
  }
 
void navigationAndSetting()//通过串口完成设置向导
{
  if(EEPROM.read(0x01)==0x00)
  {
    EEPROM.write(0x01,0xCA);//写入一个数据表示该开发板开过机运行程序过
    
      Serial.println("Which display you want to use for display data from your PC?");
      Serial.println("Input 1 for HT1621 LCD display and input 0 for FUTABA VFD");//设置显示设备
      char cho=Serial.read();
      if(cho==0 || cho==1)
      {
        EEPROM.write(0x02,cho);//0x02处存储显示模式
        }
        while(cho!=1 || cho!=0)
        {
          Serial.println("Invaild value! Please input again!");
          cho=Serial.read();
          }
          
      Serial.println("Please input the baudrate");
      Serial.println("Input 0 for 9600bps");
      Serial.println("Input 1 for 4800bps");
      Serial.println("Input 2 for 115200bps");
       char cho2=Serial.read();
      if(cho2==0 || cho2==1 || cho2==2)
      {
        EEPROM.write(0x03,cho);//0x03处存储显示模式
        }
        while(cho2!=0 || cho2!=1 || cho2!=2)
        {
          Serial.println("Invaild value! Please input again!");
          cho=Serial.read();
          }
  }
          else
          {
            Serial.println("done!");
            Serial.println("This code was written by Yamashita Samiki::Yizhou Wang");//代码所有人声明
            }
      
      }


/**************************************SERIAL PORT DATA*****************************************/
void RecData()//接收数据
{
  
  for(int i=0;i<39;i++)
  {
    frame[i]=Serial.read();
    }

int SizeofFrame;//数据计数器

if(Serial.available()>0)
{
  delay(100);
  for(int i=0;i<40;i++)
  {
    while(Serial.available()==0)//检测串口数据是否传输完毕
    {
    frame[i]=Serial.read();//从串口缓冲区接受40位数据
    SizeofFrame++;
    }
    }
  }
 if(false)//数据不完整处分数据机制,已停用
  {
    for(int i=0;i<=39;i++)
    {
      frame[i]='E';//若数据不完整（不足40位），则将数据全部清零
      }
    }
    else
    {
      UCPUbai=ascii2dec(frame[0]);
      UCPUshi=ascii2dec(frame[1]);
      UCPUge=ascii2dec(frame[2]);
      
      UGPUbai=ascii2dec(frame[3]);
      UGPUshi=ascii2dec(frame[4]);
      UGPUge=ascii2dec(frame[5]);
      
      TCPUbai=ascii2dec(frame[6]);
      TCPUshi=ascii2dec(frame[7]);
      TCPUge=ascii2dec(frame[8]);

      TGPUbai=ascii2dec(frame[9]);
      TGPUshi=ascii2dec(frame[10]);
      TGPUge=ascii2dec(frame[11]);

      URAMbai=ascii2dec(frame[12]);
      URAMshi=ascii2dec(frame[13]);
      URAMge=ascii2dec(frame[14]);
      
    //  }
    }
while(Serial.read()>=0);
}
int orig2dispD(int val)
{
  switch(val)
  {
  case 1:
  return ad2num1;
  break;
  
  case 2:
  return ad2num2;
  break;
  
  case 3:
  return ad2num3;
  break;
  
  case 4:
  return ad2num4;
  break;

  case 5:
  return ad2num5;
  break;
  
  case 6:
  return ad2num6;
  break;
  
  case 7:
  return ad2num7;
  break;
  
  case 8:
  return ad2num8;
  break;

  case 9:
  return ad2num9;
  break;
  
  case 0:
  return ad2num0;
  break;

  case 88:
  return empC;
  break;
  }
  }
void detcDisplayMode()//设置显示设备，默认采用FUTABA VFD作为显示器件
{
  if(analogRead(dispM1)>analogRead(dispM2))
  {
    SwitchDisplayMode=1;
    }
  if(analogRead(dispM2)>analogRead(dispM2))
  {
    SwitchDisplayMode=0;
    }
    else
    {
      SwitchDisplayMode=0;
      }
      SwitchDisplayMode=0;
  
  }
void MainDispHT1621(int Delaytime)//显示数据主程序,Delaytime滚动时间
{
  
    ClearLcdHT1621();
    RecData();

    
    WrAddDdat(chaT,0); 
    WrAddDdat(chaC,2); 
    WrAddDdat(chaP,4);
    WrAddDdat(chaU,6);
    
    WrAddDdat(orig2dispD(TCPUbai),18);
    WrAddDdat(orig2dispD(TCPUshi),16);
    WrAddDdat(orig2dispD(TCPUge),14);//显示CPU温度，TCPU

    WrAddDdat(ad2chatC,8);
    delay(Delaytime);
    ClearLcdHT1621();

    WrAddDdat(chaT,0); 
    WrAddDdat(chaG,2); 
    WrAddDdat(chaP,4);
    WrAddDdat(chaU,6);
    
    WrAddDdat(orig2dispD(TGPUbai),18);    
    WrAddDdat(orig2dispD(TGPUshi),16);
    WrAddDdat(orig2dispD(TGPUge),14);//显示GPU温度，TGPU
    WrAddDdat(ad2chatC,8);
    delay(Delaytime);
    ClearLcdHT1621();

    WrAddDdat(chaU,0); 
    WrAddDdat(chaG,2); 
    WrAddDdat(chaP,4);
    WrAddDdat(chaU,6);
    WrAddDdat(orig2dispD(UGPUbai),18);
    WrAddDdat(orig2dispD(UGPUshi),16);
    WrAddDdat(orig2dispD(UGPUge),14);//显示GPU占用率，UGPU

    WrAddDdat(ad2chaP,10);
    WrAddDdat(ad2chaR,8);
    delay(Delaytime);
    ClearLcdHT1621();

    WrAddDdat(chaU,0); 
    WrAddDdat(chaC,2); 
    WrAddDdat(chaP,4);
    WrAddDdat(chaU,6);
    
    WrAddDdat(orig2dispD(UCPUbai),18);
    WrAddDdat(orig2dispD(UCPUshi),16);
    WrAddDdat(orig2dispD(UCPUge),14);//显示CPU占用率，UCPU
    WrAddDdat(ad2chaP,10);
    WrAddDdat(ad2chaR,8);
    delay(Delaytime);
    ClearLcdHT1621();
      }

void MainDispFutabaVFD(int dispTime)//futaba vfd显示信息程序
{
   Clear_futaba6302();
   RecData();
   printChar_futaba6302(0,"UCPU");
   if(frame[0]==0x31 && frame[1]==0x30 && frame[2]==0x30)
   {
    printChar_futaba6302(0,"CPU 100%");//CPU占满显示OVERLOAD
    }
    else
    {
   WriteOneChar_futaba6302(5,frame[0]-0x30);
   WriteOneChar_futaba6302(6,frame[1]-0x30);
  // WriteOneChar_futaba6302(6,frame[2]-0x30);
    }
   printChar_futaba6302(7,"%");
   delay(dispTime);
   
   Clear_futaba6302();
   printChar_futaba6302(0,"UGPU");
   
   if(frame[3]==0x31 && frame[4]==0x30 && frame[5]==0x30)
   {
    printChar_futaba6302(0,"GPU 100%");
    }
    else
    {
   //WriteOneChar_futaba6302(4,frame[3]-0x30);
   WriteOneChar_futaba6302(5,frame[3]-0x30);
   WriteOneChar_futaba6302(6,frame[4]-0x30);
    }
   printChar_futaba6302(7,"%");
   delay(dispTime);

   Clear_futaba6302();
   printChar_futaba6302(0,"TGPU");
   
   WriteOneChar_futaba6302(5,frame[6]-0x30);
   WriteOneChar_futaba6302(6,frame[7]-0x30);
   printChar_custom_futaba6302(0X07,0X01);

    
   delay(dispTime);
   
   Clear_futaba6302();
   printChar_futaba6302(0,"TCPU"); 

   WriteOneChar_futaba6302(5,frame[9]-0x30);
   WriteOneChar_futaba6302(6,frame[10]-0x30);
   printChar_custom_futaba6302(0X07,0X01);
  delay(dispTime);

   Clear_futaba6302();
   printChar_futaba6302(0,"RAM"); 

   WriteOneChar_futaba6302(4,frame[12]-0x30);
   WriteOneChar_futaba6302(5,frame[13]-0x30);
   WriteOneChar_futaba6302(6,frame[14]-0x30);
   printChar_futaba6302(7,"%");
  delay(dispTime);
  ClearFrame(); 
  }

void setup() {
  navigationAndSetting();
  Serial.begin(9600);
  SendDataSEGVFD("UE 0-1-2-1 ");
  switch(EEPROM.read(0x03))
  {
  case 0:
  Serial.begin(9600);
  break;
  case 1:
  Serial.begin(4800);
  break;
  case 2:
  Serial.begin(115200);
  break;
}


 
  pinMode(CLK,OUTPUT);
  pinMode(DAT,OUTPUT);
  pinMode(CS,OUTPUT);
  pinMode(DebugMode,INPUT);
  pinMode(dispM1,INPUT);
  pinMode(dispM2,INPUT);
  pinMode(EN,OUTPUT);
  pinMode(FUTABA16EN,OUTPUT);
 // navigationAndSetting(); 
  detcDisplayMode();
  if(SwitchDisplayMode==1)//初始化HT1621
  {
  pinMode(KEY,INPUT);
  Init_HT1621();
  ClearLcdHT1621();
  }
  if(SwitchDisplayMode==0)//初始化futabaVFD
  {
    pinMode(KEY,OUTPUT);
    digitalWrite(EN,HIGH);
    digitalWrite(KEY,LOW);
    delayMicroseconds(5);
    digitalWrite(KEY,HIGH);
    init_futaba6302(0x07,0xFF);
    CustomChar_futaba6302_display(0x01);
   // printChar_custom_futaba6302(0X00,0X01);//p为显示位置 val为CGRAM地址
       
    delay(1000);
    }

}
void loop() {

switch(SwitchDisplayMode)
{
   case 1:
   while(1)
   {
   if(Serial.available()>0 && Serial.read()==0x20)
   {
       MainDispHT1621(2000);//数据帧结构应为 NNNNNNNN（0x20 0x?? ----- 0x??）
       //SerialDebugForOnline();//实时查看串口数据的函数
    }
   else
  {
    WrAddDdat(chaE,2); 
    WrAddDdat(chaR,4);
    WrAddDdat(chaR,6);
  }

   }
   break;
   case 0:
   while(1)
   {
    if(Serial.available()>0 && Serial.read()==0x20)
    {
      MainDispFutabaVFD(1000);//如果串口读取到的数据是一个空格，说明AIDA64开始传输有效数据
    }
      else//串口无数据，显示错误信息
      {
        printChar_futaba6302(0,"  HALT  ");
       /* delay(2000);
        printChar_futaba6302(0,"Vp.0.1.2");
        delay(2000);
        printChar_futaba6302(0,"EDITERED");
        delay(2000);
        printChar_futaba6302(0,"TERED BY");
        delay(2000);
        printChar_futaba6302(0,"WangYiZh");
        delay(2000);
        printChar_futaba6302(0,"ngYiZhou");
        delay(2000);
        */
        }
        
        
          }
    }
   }


  /*  
    ClearLcdHT1621();
    
    for(i=0;i<30;i+=2)
    {
     WrAddDdat(0xFF,i);
     delay(1000); 
    }  */  
    
// put your main code here, to run repeatedly:
